import { Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository, Equal, Not, IsNull } from 'typeorm'
import { Role } from '../role/entities/role.entity'
import { Staff } from '../staff/entities/staff.entity'
import { CreateAdminDto } from './dto/create-admin.dto'
import { UpdateAdminDto } from './dto/update-admin.dto'
import { Admin } from './entities/admin.entity'
import { LoginStaffDto } from 'src/modules/staff/dto/staff.dto'
import * as bcrypt from 'bcrypt'
@Injectable()
export class AdminService {
  constructor(
    @InjectRepository(Admin) private readonly admin: Repository<Admin>,
    @InjectRepository(Staff) private readonly staff: Repository<Staff>,
    @InjectRepository(Role) private readonly role: Repository<Role>
  ) {}
  async create(createAdminDto: CreateAdminDto) {
    const admin = new Admin()
    const role = await this.role.findOne({
      where: { id: createAdminDto.roleId }
    })
    const staff = await this.staff.findOne({
      where: { id: createAdminDto.staffId }
    })
    admin.name = createAdminDto.name
    admin.role = role
    admin.staff = staff
    return this.admin.save(admin)
  }
  async login(loginStaff: LoginStaffDto) {
    const admin = await this.admin.findOne({
      relations: ['role', 'staff'],
      where: {
        staff: {
          phone: Equal(loginStaff.phone)
        }
      }
    })
    if (!admin) return null
    const isMatch = await bcrypt.compare(
      loginStaff.password,
      admin.staff.password
    )
    if (isMatch) return admin
    return null
  }
  async findAll(params: {
    page: number
    pageSize: number
    isDelete?: boolean
  }) {
    const where = {}
    params.isDelete && (where['deleteDate'] = Not(IsNull()))
    const data = await this.admin.find({
      where: { ...where },
      relations: ['role', 'staff'],
      withDeleted: params.isDelete,
      skip: (params.page - 1) * params.pageSize,
      take: params.pageSize
    })
    const total = await this.admin.count({
      where: { ...where },
      withDeleted: params.isDelete
    })
    const newData = []
    data.forEach(item => {
      const { staff, role, ...rest } = item
      newData.push({
        ...rest,
        staff: {
          id: staff.id,
          name: staff.name,
          phone: staff.phone
        },
        role: {
          id: role.id,
          name: role.name
        }
      })
    })
    return { data: newData, total }
  }

  async findOne(id: number) {
    return await this.admin.findOne({
      relations: ['role', 'staff'],
      where: {
        staff: {
          id: Equal(id)
        }
      }
    })
  }
  async updateByStaffId(id: number, updateAdminDto: UpdateAdminDto) {
    const admin = await this.admin.findOne({
      relations: ['staff'],
      where: { staff: { id: Equal(id) } }
    })
    const role = await this.role.findOne({
      where: { id: updateAdminDto.roleId }
    })
    const newAdmin = new Admin()
    newAdmin.role = role
    return this.admin.update(admin.id, newAdmin)
  }

  update(id: number, updateAdminDto: UpdateAdminDto) {
    return this.admin.update(id, updateAdminDto)
  }

  remove(ids: number[]) {
    return this.admin.softDelete(ids)
  }

  restore(ids: number[]) {
    return this.admin.restore(ids)
  }
}
